package cz.vutbr.fit.dnacompress.encoding;

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.biojava.utils.ParserException;

import cz.vutbr.fit.dnacompress.events.AlignEvent;

/**
 * Koder Golomb-Rice kodu
 */
public class RiceCoder extends AbstractCoder {
	
	public RiceCoder(String countTableFileName) throws IOException, ParserException {
		
		setCountTables( countTableFileName);
		this.coderID = 3;
	}

	@Override
	public List<AlignEvent> decode(InputStream is) throws IOException, ParserException {
		
		// alokace bufferu pro cteni dat
		ByteBuffer byteBuffer = ByteBuffer.allocate( 1000);
		int r;
		while((r = is.read()) != -1) {
			byteBuffer.put((byte) r);
		}
		byteBuffer.rewind();
		
		// vytvoreni vektoru bitu
		RiceCode rc = new RiceCode( byteBuffer.array());
		// ziskani polozek ( pozice, data, pozice, data)
		int[] items = rc.getItems();
		
		List<AlignEvent> events = new ArrayList<AlignEvent>();
		int digit = 0;
		int position = 0;
		boolean switcher = true;
		// vytvoreni seznamu eventu
		for( int i=0;i<items.length;i++) {
			
			digit = items[i];
			System.out.println( digit);
			AlignEvent event = null;
			if( switcher) {
				
				position = digit;
			} else {
				
				event = AlignEvent.getClassWithData( countTableDecode.get( digit));			
				event.setPosition( position);
				
				System.out.println(event);
				events.add( event);
			}
			switcher = !switcher;
			
		}
		return events;
	}

	@Override
	public byte[] encode(List<AlignEvent> events) {
		
		// zakodovani do vektoru bitu ( m=8) -> urceno experimentalne
		RiceCode rc = new RiceCode( 8);		
		
		for( Iterator<AlignEvent> i = events.iterator(); i.hasNext();) {
			
			AlignEvent event = i.next();
			int position = event.getPosition();
			// first encode position
			rc.addItem( position);
			// second encode data
			int codeTableOffset = countTableEncode.get( event.getCountID()); 
			rc.addItem( codeTableOffset);
			
			//System.out.println( "Posiion: " + position + ", TableOffsetBits: " + codeTableOffset);
		}
		
		return rc.getBits();
	}
	
	public String toString() {
		return "Rice coder";
	}

}
